﻿using System;
using System.Diagnostics;
[assembly: CLSCompliant(false)]
namespace Microsoft.ExternalResearch.CreativeCommons.Word
{
    using System.Drawing;
    using System.IO;
    using System.Windows.Forms;
    using Microsoft.Office.Tools.Ribbon;
    using System.Xml.Linq;
    using System.Text;
    using System.Xml;
    using Word = Microsoft.Office.Interop.Word;
    using Microsoft.Office.Interop.Word;
    using Microsoft.ExternalResearch.CreativeCommons.Common;
    using Microsoft.Office.Core;
    using System.Runtime.InteropServices;
    using System.Globalization;
    using System.Resources;
    using System.Collections;

    /// <summary>
    /// Represents the ribbon UI for Creative Commons Microsoft Word add-in.
    /// </summary>
    /// 
    public partial class CreativeCommonsRibbonTab : OfficeRibbon
    {
        /// <summary>
        /// Title of the content control.
        /// </summary>
        private string licenseLogoTitle = Helper.GetString("CreativeCommonsLicense");

        /// <summary>
        /// Object used to pass Type.Missing as a ref parameter.
        /// </summary>
        private object missing = Type.Missing;

        /// <summary>
        /// Image of the license.
        /// </summary>
        private Image license;

        /// <summary>
        /// Creates an instance of this class.
        /// </summary>
        public CreativeCommonsRibbonTab()
        {
            this.InitializeComponent();
            ThisAddIn.ApplicationStartedEvent += new EventHandler(this.ThisAddInApplicationStarted);
        }



        /// <summary>
        /// Sets a value indicating whether document is licensed.
        /// </summary>
        private void DocumentLicensed(bool value)
        {
            this.licensedGallery.Visible = value;
            this.notLicensedButton.Visible = !value;
        }

        /// <summary>
        /// Sets a value indicating whether the ribbon is enabled.
        /// </summary>
        private bool RibbonEnabled
        {
            get
            {
                return this.licensesRibbonGallery.Enabled;
            }
            set
            {
                this.licensedGallery.Enabled = value;
                this.notLicensedButton.Enabled = value;
                this.licensesRibbonGallery.Enabled = value;
            }
        }

        /// <summary>
        /// Sets the license image in ribbon UI.
        /// </summary>
        private Image LicenseImage
        {
            get
            {
                return this.license;
            }
            set
            {
                LicenseInfo licenseInfo = Helper.ReadLicenseInfo((DocumentProperties)ThisAddIn.WordApplication.ActiveDocument.CustomDocumentProperties);
                this.licensedGallery.Items[0].Label = Helper.GetLicenseLabel(licenseInfo.Id);
                this.licensedGallery.Items[0].Image = value;
                this.license = value;
            }
        }

        /// <summary>
        /// Prepares the cache folders.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="e">Event arguments.</param>
        private void CreativeCommonsRibbonTabLoad(object sender, RibbonUIEventArgs e)
        {
            Helper.PrepareLicenseFolders();

            // Set localized labels
            this.tabAttributes.Label = Helper.GetString("CreativeCommons");
            this.groupCreativeCommons.Label = Helper.GetString("CreativeCommons");
            this.licensedGallery.Label = Helper.GetString("Licensed", new object[] { "Document" });
            this.notLicensedButton.Label = Helper.GetString("NotLicensed", new object[] { "Document" });
            this.licensesRibbonGallery.Label = Helper.GetString("Licenses");
            this.removeLicenseButton.Label = Helper.GetString("RemoveLicenseFromDocument", new object[] { "Document" });
            this.newLicenseButton.Label = Helper.GetString("NewLicense");
            this.removeLicensesButton.Label = Helper.GetString("RemoveLicensesFromDisk");
            this.notLicensedButton.SuperTip = Helper.GetString("LicenseIndicatorToolTip");
            this.licensedGallery.SuperTip = Helper.GetString("LicenseGalleryToolTip");
            this.licensesRibbonGallery.SuperTip = Helper.GetString("LicensesGalleryToolTip");

            this.newLicenseButton.Click += this.NewLicense;
            this.removeLicenseButton.Click += new EventHandler<RibbonControlEventArgs>(this.RemoveLicenseFromDocumentButtonClick);
            this.removeLicensesButton.Click += new EventHandler<RibbonControlEventArgs>(this.RemoveLicensesButtonClick);
            this.licensedGallery.ItemsLoading += new EventHandler<RibbonControlEventArgs>(this.LicensedGalleryItemsLoading);
        }

        /// <summary>
        /// Updates the ribbon UI.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="e">Event arguments.</param>
        private void LicensedGalleryItemsLoading(object sender, RibbonControlEventArgs e)
        {
            this.UpdateRibbonUI();
        }

        /// <summary>
        /// Associates the event handlers when application starts.
        /// </summary>
        private void ThisAddInApplicationStarted(Object sender, EventArgs e)
        {
            ThisAddIn.WordApplication.WindowActivate += new ApplicationEvents4_WindowActivateEventHandler(this.WordApplicationWindowActivate);
            ThisAddIn.WordApplication.DocumentOpen += new ApplicationEvents4_DocumentOpenEventHandler(this.WordApplicationDocumentOpen);

            // This call is required to handle the scenario when the add-in is disabled via Options and enabled again.
            this.UpdateRibbonUI();
        }

        /// <summary>
        /// Updates the ribbon UI when a document is opened.
        /// </summary>
        /// <param name="doc">Document object.</param>
        private void WordApplicationDocumentOpen(Document doc)
        {
            this.UpdateRibbonUI();
        }

        /// <summary>
        /// Updates the ribbon UI when user switches between documents.
        /// </summary>
        /// <param name="doc">Document object.</param>
        /// <param name="wn">Word window.</param>
        private void WordApplicationWindowActivate(Document doc, Window wn)
        {
            this.UpdateRibbonUI();
        }

        /// <summary>
        /// Invokes the "Remove licenses from disk" dialog.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="e">Event arguments.</param>
        private void RemoveLicensesButtonClick(object sender, RibbonControlEventArgs e)
        {
            RemoveLicensesDialog dlg = new RemoveLicensesDialog();
            dlg.ShowDialog();
        }

        /// <summary>
        /// Removes the Creative Commons license from the workbook.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="e">Event arguments.</param>
        private void RemoveLicenseFromDocumentButtonClick(object sender, RibbonControlEventArgs e)
        {
            if (null != Helper.ReadLicenseInfo((DocumentProperties)ThisAddIn.WordApplication.ActiveDocument.CustomDocumentProperties))
            {
                if (!Helper.GetUserResponse(Helper.GetString("RemoveLicenseMessageWord", new object[] { "Document" })))
                {
                    return;
                }
            }

            this.RemoveLicenseFromDocument();
            ThisAddIn.WordApplication.ActiveDocument.Saved = false;
            this.UpdateRibbonUI();
        }

        /// <summary>
        /// Removes the document property for Creative Commons license.
        /// </summary>
        private void RemoveLicenseFromDocument()
        {
            DocumentProperties customProperties = (DocumentProperties)ThisAddIn.WordApplication.ActiveDocument.CustomDocumentProperties;

            if (null != Helper.ReadLicenseInfo(customProperties))
            {
                customProperties[Helper.LicenseIdPropertyName].Delete();
                customProperties[Helper.LicenseUrlPropertyName].Delete();
                customProperties[Helper.LicenseXmlPropertyName].Delete();
            }

            ContentControls ctrls = ThisAddIn.WordApplication.ActiveDocument.SelectContentControlsByTitle(this.licenseLogoTitle);
            foreach (Word.ContentControl contentControl in ctrls)
            {
                if (contentControl.Tag.Equals(this.licenseLogoTitle) && contentControl.Title.Equals(this.licenseLogoTitle))
                {
                    contentControl.LockContentControl = false;
                    contentControl.Delete(true);
                }

            }
        }

        /// <summary>
        /// Loads and displays the available licenses in the ribbon UI.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="e">Event arguments.</param>
        private void LoadLicenses(object sender, RibbonControlEventArgs e)
        {
            this.UpdateRibbonUI();
            this.licensesRibbonGallery.Items.Clear();

            if (Directory.Exists(Helper.LocalLicensesFolderPath))
            {
                foreach (string dir in Directory.GetDirectories(Helper.LocalLicensesFolderPath))
                {
                    RibbonDropDownItem item = new RibbonDropDownItem();
                    item.Tag = dir.Substring(Helper.LocalLicensesFolderPath.Length + @"\".Length);

                    if (FileAttributes.Hidden != (File.GetAttributes(dir) & FileAttributes.Hidden))
                    {
                        continue;
                    }
                    string strLicImageFile = Path.Combine(dir, Helper.LicenseImageFileName);
                    if (!File.Exists(dir + @"\" + Helper.LicenseFileName) || !File.Exists(strLicImageFile))
                    {
                        continue;
                    }

                    try
                    {
                        item.Image = Helper.GetImageFromFile(strLicImageFile);
                    }
                    catch (FileNotFoundException)
                    {
                        // Ignore if the icon file is missing.
                    }

                    this.licensesRibbonGallery.Items.Add(item);
                    this.licensesRibbonGallery.Items[this.licensesRibbonGallery.Items.Count - 1].Label = Helper.GetLicenseLabel(item.Tag.ToString());
                }
            }

            // Disable 'Remove Licenses' button if there is no license is available for removal.
            this.removeLicensesButton.Visible = !(0 == this.licensesRibbonGallery.Items.Count);
        }

        /// <summary>
        /// Invokes the "New license" wizard.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="e">Event arguments.</param>
        private void NewLicense(object sender, RibbonControlEventArgs e)
        {
            NewLicenseWizard newLicenseWizard = new NewLicenseWizard();
            newLicenseWizard.ShowDialog();
        }

        /// <summary>
        /// Associates the selected Creative Commons license with the workbook.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="e">Event arguments.</param>
        private void AssociateLicense(object sender, RibbonControlEventArgs e)
        {
            // Warn user if the document is already associates with a license.
            if (null != Helper.ReadLicenseInfo((DocumentProperties)ThisAddIn.WordApplication.ActiveDocument.CustomDocumentProperties))
            {
                if (!Helper.GetUserResponse(Helper.GetString("ReAssociateConfirmMessageWord", new object[] { "document" })))
                {
                    return;
                }
            }

            this.RemoveLicenseFromDocument();
            string[] licenseLogoInfo = Helper.GetLicenseInfo(this.licensesRibbonGallery.Items[this.licensesRibbonGallery.SelectedItemIndex].Tag.ToString());
            licenseLogoInfo[0] = RemoveJunkCharactersFromLicenseText(licenseLogoInfo[0]);
            Image img = this.licensesRibbonGallery.Items[this.licensesRibbonGallery.SelectedItemIndex].Image;

            object lineUnit = WdUnits.wdLine;

            // We need to leave a paragraph before and after the content control so that
            // it does not crash.
            ThisAddIn.WordApplication.Selection.TypeParagraph();

            object range = ThisAddIn.WordApplication.Selection.Range;
            Paragraph para = ThisAddIn.WordApplication.ActiveDocument.Content.Paragraphs.Add(ref range);
            // Set the line spacing rule to single, so as to not clip the license image.
            para.LineSpacingRule = WdLineSpacing.wdLineSpaceSingle;
                        
            range = ThisAddIn.WordApplication.Selection.Range;
            ContentControl contentControl = ThisAddIn.WordApplication.Selection.Range.ContentControls.Add(WdContentControlType.wdContentControlRichText, ref range);
            contentControl.Tag = this.licenseLogoTitle;
            contentControl.Title = this.licenseLogoTitle;

            object collapseDirection = WdCollapseDirection.wdCollapseEnd;

            object unit = WdUnits.wdCharacter;
            object count = 1;
            ThisAddIn.WordApplication.Selection.Range.InsertXML(Helper.ConvertImageToXml(img), ref this.missing);
            ThisAddIn.WordApplication.Selection.MoveRight(ref unit, ref count, ref this.missing);
            ThisAddIn.WordApplication.Selection.TypeParagraph();

            // Insert license link and text.
            ThisAddIn.WordApplication.Selection.TypeText(licenseLogoInfo[2]);
            object text = licenseLogoInfo[0];
            object url = licenseLogoInfo[1];
            ThisAddIn.WordApplication.Selection.Range.Hyperlinks.Add(ThisAddIn.WordApplication.Selection.Range, ref url, ref this.missing, ref this.missing, ref text, ref this.missing);
            ThisAddIn.WordApplication.Selection.TypeText(licenseLogoInfo[3]);
            contentControl.LockContentControl = true;
            contentControl.LockContents = true;

            DocumentProperties customProperties = (DocumentProperties)ThisAddIn.WordApplication.ActiveDocument.CustomDocumentProperties;
            LicenseInfo licenseInfo = new LicenseInfo();
            licenseInfo.Id = this.licensesRibbonGallery.Items[this.licensesRibbonGallery.SelectedItemIndex].Tag.ToString();
            licenseInfo.LicenseUrl = url.ToString();
            licenseInfo.LicenseXml = licenseLogoInfo[4];

            // Save the license information in document.
            Helper.SaveLicenseInfo((DocumentProperties)ThisAddIn.WordApplication.ActiveDocument.CustomDocumentProperties, licenseInfo);
            ThisAddIn.WordApplication.ActiveDocument.Saved = false;

            this.license = img;

            this.UpdateRibbonUI();
        }


        /// <summary>
        /// Updates the ribbon UI based on the state of Word and document.
        /// </summary>
        private void UpdateRibbonUI()
        {
            if (null != ThisAddIn.WordApplication)
            {
                // When word is opened without a document.
                if (!ThisAddIn.HasDocument())
                {
                    this.DocumentLicensed(false);
                    this.RibbonEnabled = false;
                }

                // When the document does not have a license.
                else if (null != ThisAddIn.WordApplication.ActiveDocument && null == Helper.ReadLicenseInfo((DocumentProperties)ThisAddIn.WordApplication.ActiveDocument.CustomDocumentProperties))
                {
                    this.DocumentLicensed(false);
                    this.RibbonEnabled = true;
                }

                // When the document has a license.
                else
                {
                    if (null != ThisAddIn.WordApplication.ActiveDocument)
                    {
                        LicenseInfo licenseInfo = Helper.ReadLicenseInfo((DocumentProperties)ThisAddIn.WordApplication.ActiveDocument.CustomDocumentProperties);
                        this.RibbonEnabled = true;
                        this.DocumentLicensed(true);
                        this.LicenseImage = licenseInfo.Image;
                    }
                }
            }
        }

        /// <summary>
        /// Removes redundant characters like \r & \n from the string, also removes some extra spaces
        /// </summary>
        /// <param name="str">string from which to remove the junk characters</param>
        /// <returns>Modified string</returns>
        private string RemoveJunkCharactersFromLicenseText(string str)
        {
            try
            {
                StringBuilder strBuilder = new StringBuilder(str);
                strBuilder = strBuilder.Replace("\r\n ", "");
                strBuilder = strBuilder.Replace("\r\n", "");
                str = strBuilder.ToString();
            }
            catch (Exception)
            {
            }
            return str;
        }
    }
}
